package com.example.demo.rest;

import com.example.demo.HardwareInfoThread;
import com.example.demo.bo.City;
import com.example.demo.util.CCEngineUtill;
import com.example.demo.util.CPUUtil;
import com.example.demo.util.DBUtil;
import com.example.demo.util.GPUUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.awt.*;
import java.io.*;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author 作者 SYGIS
 * @date 创建时间：2023年12月12日
 * @version 1.0
 * @parameter
 * @since
 * @return
 */
@RestController
public class InitRest {

	protected static Logger logger = LoggerFactory.getLogger(InitRest.class);

	/**
	 * SYGIS：修改引擎类型
	 * @param vo
	 * @return
	 * @throws SQLException
	 */
	@PostMapping("/saveEngineType")
	public Map<Object,Object> saveEngineType(@RequestBody Map<Object,Object> vo) throws SQLException {
        String clusterIp = readClusterIp();
		Map<Object,Object> res = new HashMap<>();
		DBUtil.saveEngineType(vo,clusterIp);
		List<Map<Object,Object>> list = DBUtil.getEngineInfoByIPAndHostname(vo.get("server_ip").toString(),vo.get("hostname").toString(),clusterIp);
		if(list.size()>0){
			res.put("code",200);
			res.put("msg","设置成功");
			res.put("server_ip",list.get(0).get("server_ip"));
			res.put("hostname",list.get(0).get("host_name"));
			res.put("cluster_ip",list.get(0).get("cluster_ip"));
			res.put("engine_type",list.get(0).get("engine_type"));
			res.put("type_name",list.get(0).get("type_name"));
			res.put("job_path",list.get(0).get("job_path"));
			res.put("job_pathx",list.get(0).get("job_path"));
			res.put("engine_status",list.get(0).get("engine_status"));
			res.put("cc_path",list.get(0).get("cc_path"));
		}else{
			res.put("code",211);
			res.put("msg","设置失败");
			res.put("server_ip",null);
			res.put("hostname",null);
			res.put("cluster_ip",null);
			res.put("engine_type",null);
			res.put("type_name",null);
			res.put("job_path",null);
			res.put("job_pathx",null);
			res.put("engine_status",null);
			res.put("cc_path",null);
		}
		return res;
	}

	/**
	 * SYGIS：修改工作路径
	 * @param vo
	 * @return
	 * @throws SQLException
	 */
	@PostMapping("/saveJobPath")
	public Map<Object,Object> saveJobPath(@RequestBody Map<Object,Object> vo) throws SQLException {
		String clusterIp = readClusterIp();
		Map<Object,Object> res = new HashMap<>();
		DBUtil.saveJobPath(vo,clusterIp);
		List<Map<Object,Object>> list = DBUtil.getEngineInfoByIPAndHostname(vo.get("server_ip").toString(),vo.get("hostname").toString(),clusterIp);
		if(list.size()>0){
			res.put("code",200);
			res.put("msg","设置成功");
			res.put("server_ip",list.get(0).get("server_ip"));
			res.put("hostname",list.get(0).get("host_name"));
			res.put("cluster_ip",list.get(0).get("cluster_ip"));
			res.put("engine_type",list.get(0).get("engine_type"));
			res.put("type_name",list.get(0).get("type_name"));
			res.put("job_path",list.get(0).get("job_path"));
			res.put("cc_path",list.get(0).get("cc_path"));
			res.put("job_pathx",list.get(0).get("job_path"));
			res.put("engine_status",list.get(0).get("engine_status"));
		}else{
			res.put("code",211);
			res.put("msg","设置失败");
			res.put("server_ip",null);
			res.put("hostname",null);
			res.put("cluster_ip",clusterIp);
			res.put("engine_type",null);
			res.put("type_name",null);
			res.put("job_path",null);
			res.put("cc_path",null);
			res.put("job_pathx",null);
			res.put("engine_status",null);
		}
		// 设置CC 路径
		CCEngineUtill.updateCCEnv("CC_CENTER_JOBQUEUE",vo.get("job_path").toString());
		return res;
	}

	@PostMapping("/applyConfig")
	public void applyConfig(@RequestBody Map<Object,Object> vo) throws SQLException {
		String clusterIp = readClusterIp();
		List<Map<Object,Object>> list = DBUtil.getEngineInfoByIPAndHostname(vo.get("server_ip").toString(),vo.get("hostname").toString(),clusterIp);
		CCEngineUtill.restartCCEngine2(list.get(0).get("engine_type").toString(),vo.get("job_path").toString(),vo.get("cc_path").toString());
	}

	public String readClusterIp(){
		String clusterIp = "";
		try {
			File file = new File("C:\\cluster\\clusterip.txt");
			if(!file.exists()){
				clusterIp = "NoClusterIp";
			}else{
				FileReader fileReader = new FileReader(file);
				BufferedReader bufferedReader = new BufferedReader(fileReader);
				String line;
				while ((line = bufferedReader.readLine()) != null) {
					clusterIp = line;
				}
				bufferedReader.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return clusterIp;
	}

	/**
	 * SYGIS：退出集群
	 * @param vo
	 * @return
	 * @throws SQLException
	 */
	@PostMapping("/quitCluster")
	public Map<Object,Object> quitCluster(@RequestBody Map<Object,Object> vo) throws SQLException {
		String filePath = "C:\\cluster\\clusterip.txt";
		File file = new File(filePath);
		try {
			File dir = new File("C:\\cluster");
			if(!dir.exists()){
				dir.mkdirs();
			}
			if(!file.exists()){
				file.createNewFile();
			}else{
				file.delete();
				file.createNewFile();
			}
			FileWriter writer = new FileWriter(filePath);
			String data = "NoClusterIp";
			writer.write(data);
			writer.close();
		}catch (IOException e){
			e.printStackTrace();
		}
		Map<Object,Object> res = new HashMap<>();
		Integer count = DBUtil.quitCluster(vo);
		res.put("code",200);
		res.put("msg","退出集群成功");
		res.put("server_ip",null);
		res.put("hostname",vo.get("hostname"));
		res.put("cluster_ip",vo.get("cluster_ip"));
		return res;
	}

	/**
	 * SYGIS：加入集群
	 * @param vo
	 * @return
	 * @throws SQLException
	 */
	@PostMapping("/joinCluster")
	public Map<Object,Object> joinCluster(@RequestBody Map<Object,Object> vo) throws SQLException {
        String filePath = "C:\\cluster\\clusterip.txt";
		File file = new File(filePath);
		try {
			File dir = new File("C:\\cluster");
			if(!dir.exists()){
				dir.mkdirs();
			}
			if(!file.exists()){
				file.createNewFile();
			}else{
				file.delete();
				file.createNewFile();
			}
			FileWriter writer = new FileWriter(filePath);
			String data = vo.get("cluster_ip").toString();
			writer.write(data);
			writer.close();
		}catch (IOException e){
			e.printStackTrace();
		}
		// 启动上报线程
		if(!(vo.get("cluster_ip").toString().equalsIgnoreCase(null))&&!(vo.get("cluster_ip").toString().equalsIgnoreCase("null"))){
			HardwareInfoThread hardwareInfoThread = new HardwareInfoThread(vo.get("cluster_ip").toString());
			hardwareInfoThread.start();
		}
		Map<Object,Object> res = new HashMap<>();
		Integer count = DBUtil.joinCluster(vo);
		if(count>0){
			String job_path = CCEngineUtill.getJobPath("CC_CENTER_JOBQUEUE");
			String engineType = "AT,RasterProduction,TileProduction,AI";
			String engineTypeName = "全类型";
			res.put("code",200);
			res.put("msg","加入集群成功");
			res.put("server_ip",vo.get("server_ip"));
			res.put("hostname",vo.get("hostname"));
			res.put("cluster_ip",vo.get("cluster_ip"));
			res.put("job_path",job_path);
			res.put("engine_type",engineType);
			res.put("type_name",engineTypeName);
			res.put("cc_path",vo.get("cc_path"));
		}else{
			res.put("code",211);
			res.put("msg","加入集群失败");
			res.put("serve_ip",vo.get("serve_ip"));
			res.put("hostname",vo.get("hostname"));
			res.put("cluster_ip",null);
			res.put("cc_path",null);
		}
		return res;
	}

	/**
	 * SYGIS：获取集群信息
	 * @return
	 * @throws SQLException
	 */
	@PostMapping("/getClusterInfo")
	public Map<Object,Object> getClusterInfo() throws SQLException {
		String clusterIp = readClusterIp();
		Map<Object,Object> res = new HashMap<>();
		// 本机信息
		InetAddress addr = null;
		try {
			addr = InetAddress.getLocalHost();
		}catch (Exception e){
			e.printStackTrace();
		}
		String ip = addr.getHostAddress();
		String hostname = addr.getHostName();
		Map<Object,Object> engineInfo = new HashMap<>();
		String job_path = CCEngineUtill.getJobPath("CC_CENTER_JOBQUEUE");
		if(clusterIp.equalsIgnoreCase("NoClusterIp")){
			engineInfo.put("cluster_ip",clusterIp);
			engineInfo.put("engine_type",null);
			engineInfo.put("type_name",null);
			engineInfo.put("job_path",job_path);
			engineInfo.put("job_pathx",job_path);
			engineInfo.put("cc_path",null);
		}else{
			List<Map<Object,Object>> list = DBUtil.getEngineInfoByIPAndHostname(ip,hostname,clusterIp);
			if(list.size()>0){
				engineInfo.put("cluster_ip",list.get(0).get("cluster_ip"));
				engineInfo.put("engine_type",list.get(0).get("engine_type"));
				engineInfo.put("type_name",list.get(0).get("type_name"));
				engineInfo.put("job_path",list.get(0).get("job_path"));
				engineInfo.put("job_pathx",list.get(0).get("job_path"));
				engineInfo.put("cc_path",list.get(0).get("cc_path"));
			}else{
				engineInfo.put("cluster_ip",clusterIp);
				engineInfo.put("engine_type",null);
				engineInfo.put("type_name",null);
				engineInfo.put("job_path",job_path);
				engineInfo.put("job_pathx",job_path);
				engineInfo.put("cc_path",null);
			}
		}
		engineInfo.put("server_ip",ip);
		engineInfo.put("hostname",hostname);
		res.put("engine",engineInfo);
		return res;
	}

	/**
	 * SYGIS：获取客户端基本信息
	 * @return
	 * @throws InterruptedException
	 * @throws IOException
	 * @throws SQLException
	 */
	@PostMapping("/getBaseInfo")
	public Map<Object,Object> getBaseInfo() throws InterruptedException, IOException,SQLException {
		String clusterIp = readClusterIp();
		Map<Object,Object> res = new HashMap<>();
		res.put("cpu",CPUUtil.printlnCpuInfo());
		res.put("mem",CPUUtil.MemInfo());
		res.put("gpu",GPUUtil.getGPU());
		// 本机信息
		InetAddress addr = null;
		try {
			addr = InetAddress.getLocalHost();
		}catch (Exception e){
			e.printStackTrace();
		}
		String ip = addr.getHostAddress();
		String hostname = addr.getHostName();
		Map<Object,Object> engineInfo = new HashMap<>();
		String job_path = CCEngineUtill.getJobPath("CC_CENTER_JOBQUEUE");
		if(clusterIp.equalsIgnoreCase("NoClusterIp")){
			engineInfo.put("cluster_ip",clusterIp);
			engineInfo.put("engine_type",null);
			engineInfo.put("engine_type",null);
			engineInfo.put("job_path",job_path);
			engineInfo.put("engine_status",null);
		}else{
			List<Map<Object,Object>> list = DBUtil.getEngineInfoByIPAndHostname(ip,hostname,clusterIp);
			if(list.size()>0){
				engineInfo.put("cluster_ip",list.get(0).get("cluster_ip"));
				engineInfo.put("engine_type",list.get(0).get("engine_type"));
				engineInfo.put("type_name",list.get(0).get("type_name"));
				engineInfo.put("job_path",list.get(0).get("job_path"));
				engineInfo.put("engine_status",list.get(0).get("engine_status"));
			}else{
				engineInfo.put("cluster_ip",clusterIp);
				engineInfo.put("engine_type",null);
				engineInfo.put("engine_type",null);
				engineInfo.put("job_path",job_path);
				engineInfo.put("engine_status",null);
			}
		}
		res.put("engine",engineInfo);
		return res;
	}

	@PostMapping("/getBaseInfoInit")
	public Map<Object,Object> getBaseInfoInit() throws InterruptedException, IOException,SQLException {
		String clusterIp = readClusterIp();
		// 启动上报线程
		if(!(clusterIp.equalsIgnoreCase("NoClusterIp"))){
			HardwareInfoThread hardwareInfoThread = new HardwareInfoThread(clusterIp);
			hardwareInfoThread.start();
		}
		Map<Object,Object> res = new HashMap<>();
		res.put("cpu",CPUUtil.printlnCpuInfo());
		res.put("mem",CPUUtil.MemInfo());
		res.put("gpu",GPUUtil.getGPU());
		// 本机信息
		InetAddress addr = null;
		try {
			addr = InetAddress.getLocalHost();
		}catch (Exception e){
			e.printStackTrace();
		}
		String ip = addr.getHostAddress();
		String hostname = addr.getHostName();
		Map<Object,Object> engineInfo = new HashMap<>();
		String job_path = CCEngineUtill.getJobPath("CC_CENTER_JOBQUEUE");
		if(clusterIp.equalsIgnoreCase("NoClusterIp")){
			engineInfo.put("cluster_ip",clusterIp);
			engineInfo.put("engine_type",null);
			engineInfo.put("engine_type",null);
			engineInfo.put("job_path",job_path);
			engineInfo.put("engine_status",null);
		}else{
			List<Map<Object,Object>> list = DBUtil.getEngineInfoByIPAndHostname(ip,hostname,clusterIp);
			if(list.size()>0){
				engineInfo.put("cluster_ip",list.get(0).get("cluster_ip"));
				engineInfo.put("engine_type",list.get(0).get("engine_type"));
				engineInfo.put("type_name",list.get(0).get("type_name"));
				engineInfo.put("job_path",list.get(0).get("job_path"));
				engineInfo.put("engine_status",list.get(0).get("engine_status"));
			}else{
				engineInfo.put("cluster_ip",clusterIp);
				engineInfo.put("engine_type",null);
				engineInfo.put("engine_type",null);
				engineInfo.put("job_path",job_path);
				engineInfo.put("engine_status",null);
			}
		}
		res.put("engine",engineInfo);
		return res;
	}

	/**
	 * SYGIS：操作客户端CC引擎
	 * @param vo
	 * @return
	 * @throws SQLException
	 */
	@PostMapping("/operateEngineAction")
	public Map<Object,Object> operateEngineAction(@RequestBody Map<Object,Object> vo) throws SQLException {
		Map<Object,Object> res = new HashMap<>();
		// 本机信息
		InetAddress addr = null;
		try {
			addr = InetAddress.getLocalHost();
		}catch (Exception e){
			e.printStackTrace();
		}
		String ip = addr.getHostAddress();
		String hostname = addr.getHostName();
		String clusterIp = readClusterIp();
		List<Map<Object,Object>> list = DBUtil.getEngineInfoByIPAndHostname(ip,hostname,clusterIp);
		String type = list.get(0).get("engine_type").toString();
		if(vo.get("operation").toString().equalsIgnoreCase("start")){
			DBUtil.updateEngineRestartInfo(ip,hostname,clusterIp);
			CCEngineUtill.startCCEngine(type,list.get(0).get("job_path").toString(),list.get(0).get("cc_path").toString());
		}else if(vo.get("operation").toString().equalsIgnoreCase("stop")){
			DBUtil.updateEngineStopInfo(ip,hostname,clusterIp);
			CCEngineUtill.stopCCEngine();
		}else if(vo.get("operation").toString().equalsIgnoreCase("restart")){
			DBUtil.updateEngineRestartInfo(ip,hostname,clusterIp);
			CCEngineUtill.restartCCEngine(type,list.get(0).get("job_path").toString(),list.get(0).get("cc_path").toString());
		}
		res.put("code",200);
		res.put("msg","操作成功");
		return res;
	}

	/**
	 * http://localhost:9500/operateEngine
	 *
	 * @return
	 */
	/**
	 * 操作 CC 引擎：停、启和重启
	 * @param
	 */

	@PostMapping("/operateEngine")
	public void operateEngine(@RequestBody City city){
		String type = city.getType();
		try {
			String engineStatus = "";
			if(city.getType().equalsIgnoreCase("stop")){
				engineStatus = "异常";
			}else{
				engineStatus = "正常";
			}
			DBUtil.editEngineInfo(city.getIp(),city.getEngineTypeCname(),engineStatus);
		}catch (SQLException e){
			e.printStackTrace();
		}
		if(type.equals("start")){
			CCEngineUtill.startCCEngine(city.getEngineType(),null,null);
		}else if(type.equals("stop")){
			CCEngineUtill.stopCCEngine();
		}else if(type.equals("restart")){
			CCEngineUtill.restartCCEngine(city.getEngineType(),null,null);
		}
	}

	/**
	 * http://localhost:9500/editJobsPath
	 *
	 * @return
	 */
	/**
	 * 修改 CC 工作路径
	 * @param city
	 */
	@PostMapping("/editJobsPath")
	public void editJobsPath(@RequestBody City city){
		CCEngineUtill.updateCCEnv("CC_CENTER_JOBQUEUE",city.getPath());
	}

	/**
	 * http://localhost:9500/editEngineType
	 *
	 * @return
	 */
	/**
	 * 设置 CC 引擎类型
	 * @param city
	 */
	@PostMapping("/editEngineType")
	public void editEngineType(@RequestBody City city){
		String ip = city.getIp();
		String engineType = city.getEngineTypeCname();
		try {
			DBUtil.operateEngineInfo(ip,engineType);
		}catch (SQLException e){
			e.printStackTrace();
		}
		CCEngineUtill.restartCCEngine(city.getEngineType(),null,null);
	}

}
